/*! `wren` grammar compiled for Highlight.js 11.10.0 */
var hljsGrammar = (function () {
  'use strict';

  /*
  Language: Wren
  Description: Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.
  Category: scripting
  Author: @joshgoebel
  Maintainer: @joshgoebel
  Website: https://wren.io/
  */

  /** @type LanguageFn */
  function wren(hljs) {
    const regex = hljs.regex;
    const IDENT_RE = /[a-zA-Z]\w*/;
    const KEYWORDS = [
      "as",
      "break",
      "class",
      "construct",
      "continue",
      "else",
      "for",
      "foreign",
      "if",
      "import",
      "in",
      "is",
      "return",
      "static",
      "var",
      "while"
    ];
    const LITERALS = [
      "true",
      "false",
      "null"
    ];
    const LANGUAGE_VARS = [
      "this",
      "super"
    ];
    const CORE_CLASSES = [
      "Bool",
      "Class",
      "Fiber",
      "Fn",
      "List",
      "Map",
      "Null",
      "Num",
      "Object",
      "Range",
      "Sequence",
      "String",
      "System"
    ];
    const OPERATORS = [
      "-",
      "~",
      /\*/,
      "%",
      /\.\.\./,
      /\.\./,
      /\+/,
      "<<",
      ">>",
      ">=",
      "<=",
      "<",
      ">",
      /\^/,
      /!=/,
      /!/,
      /\bis\b/,
      "==",
      "&&",
      "&",
      /\|\|/,
      /\|/,
      /\?:/,
      "="
    ];
    const FUNCTION = {
      relevance: 0,
      match: regex.concat(/\b(?!(if|while|for|else|super)\b)/, IDENT_RE, /(?=\s*[({])/),
      className: "title.function"
    };
    const FUNCTION_DEFINITION = {
      match: regex.concat(
        regex.either(
          regex.concat(/\b(?!(if|while|for|else|super)\b)/, IDENT_RE),
          regex.either(...OPERATORS)
        ),
        /(?=\s*\([^)]+\)\s*\{)/),
      className: "title.function",
      starts: { contains: [
        {
          begin: /\(/,
          end: /\)/,
          contains: [
            {
              relevance: 0,
              scope: "params",
              match: IDENT_RE
            }
          ]
        }
      ] }
    };
    const CLASS_DEFINITION = {
      variants: [
        { match: [
          /class\s+/,
          IDENT_RE,
          /\s+is\s+/,
          IDENT_RE
        ] },
        { match: [
          /class\s+/,
          IDENT_RE
        ] }
      ],
      scope: {
        2: "title.class",
        4: "title.class.inherited"
      },
      keywords: KEYWORDS
    };

    const OPERATOR = {
      relevance: 0,
      match: regex.either(...OPERATORS),
      className: "operator"
    };

    const TRIPLE_STRING = {
      className: "string",
      begin: /"""/,
      end: /"""/
    };

    const PROPERTY = {
      className: "property",
      begin: regex.concat(/\./, regex.lookahead(IDENT_RE)),
      end: IDENT_RE,
      excludeBegin: true,
      relevance: 0
    };

    const FIELD = {
      relevance: 0,
      match: regex.concat(/\b_/, IDENT_RE),
      scope: "variable"
    };

    // CamelCase
    const CLASS_REFERENCE = {
      relevance: 0,
      match: /\b[A-Z]+[a-z]+([A-Z]+[a-z]+)*/,
      scope: "title.class",
      keywords: { _: CORE_CLASSES }
    };

    // TODO: add custom number modes
    const NUMBER = hljs.C_NUMBER_MODE;

    const SETTER = {
      match: [
        IDENT_RE,
        /\s*/,
        /=/,
        /\s*/,
        /\(/,
        IDENT_RE,
        /\)\s*\{/
      ],
      scope: {
        1: "title.function",
        3: "operator",
        6: "params"
      }
    };

    const COMMENT_DOCS = hljs.COMMENT(
      /\/\*\*/,
      /\*\//,
      { contains: [
        {
          match: /@[a-z]+/,
          scope: "doctag"
        },
        "self"
      ] }
    );
    const SUBST = {
      scope: "subst",
      begin: /%\(/,
      end: /\)/,
      contains: [
        NUMBER,
        CLASS_REFERENCE,
        FUNCTION,
        FIELD,
        OPERATOR
      ]
    };
    const STRING = {
      scope: "string",
      begin: /"/,
      end: /"/,
      contains: [
        SUBST,
        {
          scope: "char.escape",
          variants: [
            { match: /\\\\|\\["0%abefnrtv]/ },
            { match: /\\x[0-9A-F]{2}/ },
            { match: /\\u[0-9A-F]{4}/ },
            { match: /\\U[0-9A-F]{8}/ }
          ]
        }
      ]
    };
    SUBST.contains.push(STRING);

    const ALL_KWS = [
      ...KEYWORDS,
      ...LANGUAGE_VARS,
      ...LITERALS
    ];
    const VARIABLE = {
      relevance: 0,
      match: regex.concat(
        "\\b(?!",
        ALL_KWS.join("|"),
        "\\b)",
        /[a-zA-Z_]\w*(?:[?!]|\b)/
      ),
      className: "variable"
    };

    // TODO: reconsider this in the future
    const ATTRIBUTE = {
      // scope: "meta",
      scope: "comment",
      variants: [
        {
          begin: [
            /#!?/,
            /[A-Za-z_]+(?=\()/
          ],
          beginScope: {
            // 2: "attr"
          },
          keywords: { literal: LITERALS },
          contains: [
            // NUMBER,
            // VARIABLE
          ],
          end: /\)/
        },
        {
          begin: [
            /#!?/,
            /[A-Za-z_]+/
          ],
          beginScope: {
            // 2: "attr"
          },
          end: /$/
        }
      ]
    };

    return {
      name: "Wren",
      keywords: {
        keyword: KEYWORDS,
        "variable.language": LANGUAGE_VARS,
        literal: LITERALS
      },
      contains: [
        ATTRIBUTE,
        NUMBER,
        STRING,
        TRIPLE_STRING,
        COMMENT_DOCS,
        hljs.C_LINE_COMMENT_MODE,
        hljs.C_BLOCK_COMMENT_MODE,
        CLASS_REFERENCE,
        CLASS_DEFINITION,
        SETTER,
        FUNCTION_DEFINITION,
        FUNCTION,
        OPERATOR,
        FIELD,
        PROPERTY,
        VARIABLE
      ]
    };
  }

  return wren;

})();
;
export default hljsGrammar;